
package com.rasenhund.android.paintstock;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;
import java.util.ArrayList;

import android.app.ProgressDialog;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.SimpleOnPageChangeListener;
import android.view.Menu;

import com.rasenhund.android.paintstock.common.Const;
import com.rasenhund.android.paintstock.dao.KanriDao;
import com.rasenhund.android.paintstock.dao.StockDao;
import com.rasenhund.android.paintstock.schema.Kanri;
import com.rasenhund.android.paintstock.schema.Stock;

/**
 * メイン画面<br />
 * 在庫あり、すべて、シリーズから探すの3画面をViewPagerにて表示<br />
 * 各画面の処理は別クラスに記載<br />
 * ListFragment - 在庫あり<br />
 * ExpListFragment - シリーズから探す<br />
 */
public class MainActivity extends FragmentActivity {

    StockListFragment mFragment = null;

    /**
     * The {@link android.support.v4.view.PagerAdapter} that will provide
     * fragments for each of the sections. We use a
     * {@link android.support.v4.app.FragmentPagerAdapter} derivative, which
     * will keep every loaded fragment in memory. If this becomes too memory
     * intensive, it may be best to switch to a
     * {@link android.support.v4.app.FragmentStatePagerAdapter}.
     */
    SectionsPagerAdapter mSectionsPagerAdapter;

    /**
     * The {@link ViewPager} that will host the section contents.
     */
    ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);
        mViewPager.setOnPageChangeListener(viewPager_OnOnPageChangeListener);

        if (!checkDataBaseExists()) {

            // 最初の更新時はそのままコピー
            copyAssetsFile(Const.DB_NAME, getDbPath(Const.DB_NAME));

        } else {

            // マスタデータ更新
            updateDb();

        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        // getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    // @Override
    // public boolean onMenuItemSelected(int featureId, MenuItem item) {
    //
    // switch (item.getItemId()) {
    //
    // case R.id.action_reload:
    // ((StockListFragment) mSectionsPagerAdapter.getItem(0)).getData();
    // // ((StockListFragment)
    // // mSectionsPagerAdapter.getItem(1)).getData();
    // break;
    //
    // default:
    // break;
    //
    // }
    //
    // return super.onMenuItemSelected(featureId, item);
    // }

    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {

            Fragment fragment;

            if (position == 2) {
                fragment = new SeriesListFragment();
            } else {
                fragment = new StockListFragment();
                Bundle args = new Bundle();
                args.putInt(StockListFragment.KEY_SECTION_NUMBER, position);
                fragment.setArguments(args);

                if (position == 0) {
                    mFragment = (StockListFragment) fragment;
                }

            }

            return fragment;

        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 3;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            // Locale l = Locale.getDefault();
            switch (position) {
                case 0:
                    return getString(R.string.title_section1);
                case 1:
                    return getString(R.string.title_section2);
                case 2:
                    return getString(R.string.title_section3);
            }
            return null;
        }
    }

    /**
     * ページ変更時の処理
     */
    SimpleOnPageChangeListener viewPager_OnOnPageChangeListener = new ViewPager.SimpleOnPageChangeListener() {

        public void onPageSelected(int position) {

            if (position == 0) {
                // 在庫ありリストは随時更新
                mFragment.getData();
            }

        };

    };

    /**
     * データベースファイルパスの取得
     * 
     * @param sDbName
     * @return
     */
    private String getDbPath(String sDbName) {
        return new File(this.getFilesDir(), sDbName).getPath();
    }

    /**
     * Assetsファイルのコピー
     * 
     * @param sFileName
     * @param sNewDbName
     * @return
     */
    private boolean copyAssetsFile(String sFileName, String sCopyTo) {

        boolean bRet = false;

        try {

            // Assets配下のファイルを読む場合、FileChannelが使えない
            InputStream myInput = getResources().getAssets().open(sFileName);
            OutputStream myOutput = new FileOutputStream(sCopyTo);

            byte[] buffer = new byte[2048];
            int length;
            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }
            myOutput.flush();
            myOutput.close();
            myInput.close();

            bRet = true;

        } catch (IOException e) {
            // e.printStackTrace();
        }

        return bRet;
    }

    /**
     * ファイルコピー処理
     * 
     * @param sCopyFrom
     * @param sCopyTo
     * @return
     */
    private boolean CopyFile(String sCopyFrom, String sCopyTo) {

        try {

            FileChannel inputChannel = new FileInputStream(new File(sCopyFrom)).getChannel();
            FileChannel outputChannel = new FileOutputStream(new File(sCopyTo)).getChannel();

            inputChannel.transferTo(0, inputChannel.size(), outputChannel);

            inputChannel.close();
            outputChannel.close();

        } catch (FileNotFoundException e) {
            // TODO: handle exception
        } catch (IOException e) {
            // TODO: handle exception
        }

        return true;
    }

    /**
     * Databaseの存在チェック
     * 
     * @return
     */
    private boolean checkDataBaseExists() {

        SQLiteDatabase db = null;

        try {
            db = SQLiteDatabase.openDatabase(getDbPath(Const.DB_NAME), null,
                    SQLiteDatabase.NO_LOCALIZED_COLLATORS);
        } catch (Exception e) {
            // TODO: handle exception
        }

        if (db != null) {
            db.close();
        }

        return (db != null) ? true : false;

    }

    /**
     * マスタデータ更新処理
     */
    private void updateDb() {

        // DBファイルを一旦別名でコピーする
        copyAssetsFile(Const.DB_NAME, getDbPath(Const.NEW_DB_NAME));

        // 管理マスタ取得
        Kanri kanri = new KanriDao(getApplicationContext()).select();
        Kanri kanriNew = new KanriDao(getApplicationContext(), Const.NEW_DB_NAME).select();

        // 端末内のDBバージョン < パッケージ内のDBバージョンの場合
        if (kanri.getMaster_version() < kanriNew.getMaster_version()) {

            AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() {

                ProgressDialog mProgressDialog = null;

                /**
                 * 実行前処理
                 */
                @Override
                protected void onPreExecute() {
                    super.onPreExecute();

                    // ダイアログ表示
                    mProgressDialog = ProgressDialog.show(MainActivity.this, "", "マスタデータ更新中...");

                }

                /**
                 * 非同期処理
                 */
                @Override
                protected Boolean doInBackground(Void... params) {

                    boolean bRet = true;

                    // Stock テーブル内の全データを取得
                    ArrayList<Stock> stocks = new ArrayList<Stock>();
                    stocks = new StockDao(getApplicationContext()).selectAll();

                    // 新しいDBに全件Insert
                    if (stocks.size() > 0) {
                        StockDao daoNew = new StockDao(getApplicationContext(),
                                Const.NEW_DB_NAME);
                        if (daoNew.insertAll(stocks) == -1) {
                            bRet = false;
                        }
                    }

                    return bRet;
                }

                /**
                 * 非同期処理完了
                 */
                @Override
                protected void onPostExecute(Boolean result) {
                    super.onPostExecute(result);

                    if (result) {

                        // 処理成功時、DBファイル入れ替え

                        String sDbFilePath = getDbPath(Const.DB_NAME);
                        String sBackupPath = sDbFilePath + ".bak";
                        String sNewDbFilePath = getDbPath(Const.NEW_DB_NAME);

                        // 一つ前のバックアップは消す
                        deleteFile(Const.DB_NAME + ".bak");

                        // master.db -> master.db.bak にコピー
                        // ※念のため、バックアップは1世代保持する
                        CopyFile(sDbFilePath, sBackupPath);

                        // master_new.db -> master.dbにコピー
                        CopyFile(sNewDbFilePath, sDbFilePath);

                        // 一時ファイル削除
                        deleteFile(Const.NEW_DB_NAME);

                    }

                    // ダイアログを閉じる
                    if (mProgressDialog != null) {
                        mProgressDialog.dismiss();
                        mProgressDialog = null;
                    }

                }

            };

            task.execute();

        }

    }

}
